home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CD ROM Paradise Collection 4
/
CD ROM Paradise Collection 4 1995 Nov.iso
/
graphics
/
3dvect37.zip
/
STARS.ASM
< prev
next >
Wrap
Assembly Source File
|
1994-06-22
|
11KB
|
391 lines
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;
; Filename : STARS.ASM
; Included from: Main assembley module
; Description : Font and cosmetic screen handling routines.
; This basically draws backgound screens/opening menus.
; Have you played Red Baron or Aces of the Pacific? It's
; kind of like that.
;
; Written by: John McCarthy
; 1316 Redwood Lane
; Pickering, Ontario.
; Canada, Earth, Milky Way (for those out-of-towners)
; L1X 1C5
;
; Internet/Usenet: BRIAN.MCCARTHY@CANREM.COM
; Fidonet: Brian McCarthy 1:229/15
; RIME/Relaynet: ->CRS
;
; Home phone, (905) 831-1944, don't call at 2 am eh!
;
; Send me your protected mode source code!
; Send me your Objects!
; But most of all, Send me a postcard!!!!
;
; Display backgound stars, 1024 stars. Routine is designed so only stars
; which will be on the screen are calculated. This is first done with
; x angle indexing, then with y angle clipping, then with z distance clipping.
; this way, stars which most likely wont be visable are not rotated with those
; time-consuming IMUL's. a mode has also been added to make non-perfect 3d
; stars. this mode requires that the constants xstar and ystar be adjusted
; by the user the make the stars "look" the same as perfectly calculated stars
; however, when these values are adjusted correctly, this routine is about 40%
; faster. this can be done because the stars are at a constant distance from
; the camera.
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
.386p
jumps
code32 segment para public use32
assume cs:code32, ds:code32
include pmode.ext ; protected mode externals
include xmode.ext ; include externals for xmode routines
include 3d.ext
include equ.inc ; every .asm should have access to this stuff
include macros.inc
include stardata.inc
public show_stars
public starcolour
; angle tolerence (lower untill stars get clipped)
largest equ 150 ; this is good without using z rotations in 320x400
; this is only used when perfect_stars = yes
zdistance equ 14500 ; z clipping parameter, 16384 = all stars clipped
xstar equ ratiox*4/128 ; these are divided by 4 to give decimals.
ystar equ ratioy*4/128 ; used when perfect_stars=no
number_of_stars equ 1024 ; must be 2^some_number
cut equ 5
;use_half_stars equ no ; both already defined in equ.inc
;perfect_stars equ no ; fast star calculation if no
smatrix dd 6 dup (0) ; star matrix, ematrix*xscale*yscale
angle_count dw 0
starhalfpoint dw 512 ;400,600? ; lower cutoff if use_half_stars = yes
starcolour dd 00c0d0e0fh ; colours for 4 stars
we_is_out_of_here:
ret
show_stars:
mov si,eyeax ; get camera x angle
add esi,16384 ; 1/4 quadrant
shr esi,5 ; 32768/2^5 = 1024
and esi,000007ffh
mov ebp,esi
add ebp,largest ; sweep to bottom
sub esi,largest ; start from top
cmp ebp,number_of_stars-cut
jle s okmax
mov ebp,number_of_stars-cut
okmax:
cmp esi,cut
jge s ok_min
mov esi,cut ; looking almost directly up
ok_min:
movzx esi,xn1[esi]
movzx ebp,xn1[ebp]
mov eax,ebp
sub eax,esi
shl eax,2
mov angle_count,ax
shl esi,2
;mov angle_count,number_of_stars
;mov esi,0 ; uncomment this!! (along with stuff below)
if use_half_stars eq yes
cmp esi,starhalfpoint
jae s we_is_out_of_here
endif
call set_star_matrix ; pre-cal star matrix
more_stars:
mov al,sya[esi] ; star_y_angle
neg al
sub al,byte ptr eyeay+1
mov bl,tol[esi] ; bx = tol *256
mov cl,bl
shr cl,1
movsx ecx,cl
add al,cl
cmp al,bl
ja skipit ; try removing these skipit jumps!!!
doit:
push esi
movsx ebx,sxl[esi] ; star_x_location
movsx ecx,syl[esi]
movsx ebp,szl[esi]
if perfect_stars eq yes
shl ebx,7 ; * for some accuracy
shl ecx,7
shl ebp,7
call srotatez ; star is eligable, calculate actual screen loc
;add esi,35000 ; try this too! (this is the best part)
cmp esi,zdistance ; clip if too close (not on apex of sphere)
jl abort_s
endif
call srotatex ; check tolerence in parts (saves imul's)
if perfect_stars eq yes
mov eax,edi ; some code from make3d routine (math.inc)
cdq
idiv esi ; if fast mode selected, avoid idiv's
mov edi,eax
endif
cmp di,xmins ; draw single point/bullet
jl s abort_s
cmp di,xmaxs
jge s abort_s
call srotatey ; x is ok, solve for y
if perfect_stars eq yes
mov eax,ecx
cdq
idiv ebp
mov ecx,eax
endif
cmp cx,ymins
jl s abort_s
cmp cx,ymaxs ; ymaxs1 if larger star (for high res screens)
jge abort_s
mov edi, current_page ; point to active vga page
add bx,xcent
add cx,ycent
movzx esi,cx
mov eax,[esi*4+fastimultable] ; get offset to start of line
mov cl, bl ; copy to extract plane # from
shr bx, 2 ; x offset (bytes) = xpos/4
add ebx, eax ; offset = width*ypos + xpos/4
mov ax, map_mask_plane1 ; map mask & plane select register
and cl, plane_bits ; get plane bits
shl ah, cl ; get plane select value
out_16 sc_index, ax ; select plane
pop eax ; select colour for star
push eax
and eax,3 ; four colours
mov al,byte ptr starcolour[eax]
and ebx,0000ffffh
mov b [edi+ebx],al ; draw pixel
; add edi,xactual/4
; mov b [edi+ebx],al ; draw larger pixel
; if drawing larger star, change above code to this!
; cmp cx,ymaxs1
; jge s abort_s
abort_s:
pop esi
skipit:
if use_half_stars eq yes
cmp si,starhalfpoint
jae outhandle
else
cmp esi,number_of_stars-1-cut
jae s outhandle
endif
inc esi
dec angle_count
jnz more_stars
outhandle:
if useborders eq yes
mov ax,xmin
mov bx,xmax
mov cx,ymin
mov dx,ymax
dec ebx
dec edx
mov lxupdate+0,ax
mov lxupdate+2,bx
mov lyupdate+0,cx
mov lyupdate+2,dx
endif
ret
; pre-multiply ematrix_row*constant_for_row
; to generate new matrix
; this can be done because we don't have any
; camera location offsets (stars are at a
; fixed distance from the camera)
align 16
if perfect_stars eq yes
set_star_matrix:
mov ebx,ematrix+0
cmul eax,ebx,ratiox
mov smatrix+0,eax
if usez eq yes ; if not using z rotation, ematrix+4 =0
mov ebx,ematrix+4
cmul eax,ebx,ratiox
mov smatrix+4,eax
endif
mov ebx,ematrix+8
cmul eax,ebx,ratiox
mov smatrix+8,eax
mov ebx,ematrix+12
cmul eax,ebx,ratioy
mov smatrix+12,eax
mov ebx,ematrix+16
cmul eax,ebx,ratioy
mov smatrix+16,eax
mov ebx,ematrix+20
cmul eax,ebx,ratioy
mov smatrix+20,eax
ret
; if perfect_stars = no, stars will not go through correct 3d calculation
; but will be calculated 40% faster. you must set the values xstar and
; ystar to 3d quick multipliers so this matrix calculation makes the
; stars "look" the same. I did this by moving the camera around and testing
; if the stars moved the same as the objects. I did this because the objects
; go through the correct 3d calculation and this gave me a base by which to
; adjust these numbers.
else
set_star_matrix:
mov ebx,ematrix+0
cmul eax,ebx,xstar
shr eax,2
mov smatrix+0,eax
if usez eq yes ; if not using z rotation, ematrix+4 =0
mov ebx,ematrix+4
cmul eax,ebx,xstar
shr eax,2
mov smatrix+4,eax
endif
mov ebx,ematrix+8
cmul eax,ebx,xstar
shr eax,2
mov smatrix+8,eax
mov ebx,ematrix+12
cmul eax,ebx,ystar
shr eax,2
mov smatrix+12,eax
mov ebx,ematrix+16
cmul eax,ebx,ystar
shr eax,2
mov smatrix+16,eax
mov ebx,ematrix+20
cmul eax,ebx,ystar
shr eax,2
mov smatrix+20,eax
ret
endif
; rotate star using smatrix (imported from math.inc)
align 16
srotatex:
mov eax,smatrix+8
imul ebp
shrd eax,edx,14
mov edi,eax
if usez eq yes
mov eax,smatrix+4
imul ecx
shrd eax,edx,14
add edi,eax
endif
mov eax,smatrix+0
imul ebx
shrd eax,edx,14
add edi,eax ; di = new x
ret
align 16
srotatey:
mov eax,smatrix+16
imul ecx
shrd eax,edx,14
mov ecx,eax
mov eax,smatrix+20
imul ebp
shrd eax,edx,14
add ecx,eax
mov eax,smatrix+12
imul ebx
shrd eax,edx,14
add ecx,eax ; cx = new y
mov ebp,esi
mov ebx,edi
ret
if perfect_stars eq yes
align 16
srotatez:
mov eax,ematrix+32
imul ebp
shrd eax,edx,14
mov esi,eax
mov eax,ematrix+28
imul ecx
shrd eax,edx,14
add esi,eax
mov eax,ematrix+24
imul ebx
shrd eax,edx,14
add esi,eax ; si = new z
ret
endif
code32 ends
end